import { RedisPublisher } from "@core/redis/redis.publisher";
import { RedisSubscriber } from "@core/redis/redis.subscriber";
import { eventChannelName } from "@events/event.channel";
import { ServiceCommandType, ServiceCommand } from "@commands/service.command";
import { createPublisher, createSubscriber } from "@core/redis/message.wrapper";
import { ServiceStatusBo, ServiceStatus } from "@services/service.status.bo";

class ServiceRegister {
  private subscriber: RedisSubscriber;
  private publisher: RedisPublisher;
  private servicesStatus: ServiceStatusBo[] = [];

  constructor() {
    this.subscriber = createSubscriber();
    this.publisher = createPublisher();
    this.servicesStatus = [];

    this.init();
  }

  private init() {
    const observable = this.subscriber.subscribe<ServiceStatusBo>(
      eventChannelName.systemEventChannel.service_status_update
    );

    observable.subscribe({
      next: (serviceStatus) => {
        this.update(serviceStatus);
      },
    });
  }

  private update(serviceStatus: ServiceStatusBo): void {
    console.log("service.register.ts", "update", JSON.stringify(serviceStatus));

    const index = this.servicesStatus.findIndex(
      (t) => t.name === serviceStatus.name
    );

    if (index !== -1) {
      this.servicesStatus[index] = serviceStatus;
    } else {
      this.servicesStatus.push(serviceStatus);
    }
  }

  getServiceStatus(): ServiceStatusBo[] {
    return this.servicesStatus;
  }

  getServiceStatusByName(serviceName: string): ServiceStatusBo | undefined {
    return this.servicesStatus.find((t) => t.name === serviceName);
  }

  disposeAllServices(): void {
    this.servicesStatus.forEach((service) => {
      const serviceCommand = new ServiceCommand(
        ServiceCommandType.dispose_service,
        service.name
      );

      this.publisher.publish(
        eventChannelName.systemEventChannel.service_command,
        serviceCommand
      );
    });
  }

  quite(): void {
    this.publisher.dispose();
    this.subscriber.dispose();
  }
}

const serviceRegister = new ServiceRegister();
export { serviceRegister };
